package com.thinkTank.oa.controller;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.StringUtil;
import com.thinkTank.oa.common.Constant;
import com.thinkTank.oa.common.SystemGlobals;
import com.thinkTank.oa.configuration.Log;
import com.thinkTank.oa.configuration.RefPid;
import com.thinkTank.oa.entity.ButtDetails;
import com.thinkTank.oa.entity.Customer;
import com.thinkTank.oa.entity.Demand;
import com.thinkTank.oa.entity.Dictiontry;
import com.thinkTank.oa.entity.ImportProject;
import com.thinkTank.oa.entity.Person;
import com.thinkTank.oa.entity.Project;
import com.thinkTank.oa.entity.ProjectAttr;
import com.thinkTank.oa.entity.ProjectOfPerson;
import com.thinkTank.oa.entity.Subscribe;
import com.thinkTank.oa.entity.User;
import com.thinkTank.oa.lucene.IsolrOperation;
import com.thinkTank.oa.lucene.LuceneCustomer;
import com.thinkTank.oa.lucene.LuceneDemand;
import com.thinkTank.oa.lucene.LucenePerson;
import com.thinkTank.oa.lucene.LuceneProject;
import com.thinkTank.oa.lucene.Pagination;
import com.thinkTank.oa.lucene.SolrOperation;
import com.thinkTank.oa.service.CustomerService;
import com.thinkTank.oa.service.DemandService;
import com.thinkTank.oa.service.DetailsService;
import com.thinkTank.oa.service.DictiontryService;
import com.thinkTank.oa.service.PersonService;
import com.thinkTank.oa.service.ProjectAttrService;
import com.thinkTank.oa.service.ProjectOfPersonService;
import com.thinkTank.oa.service.ProjectService;
import com.thinkTank.oa.service.SubscribeService;
import com.thinkTank.oa.util.ExcelUtil;
import com.thinkTank.oa.util.FileUtils;
import com.thinkTank.oa.util.StrUtil;

/**
 * 项目控制器
 * 
 * @author pdz
 * @date 2018年8月8日
 */
@Controller
@RequestMapping("/project")
public class ProjectController extends BaseController {
    private final Logger logger = LoggerFactory.getLogger(ProjectController.class);

    @Resource
    private DictiontryService dictionaryService;
    @Resource
    private ProjectService projectService;
    @Resource
    private ProjectAttrService projectAttrService;
    @Resource
    private PersonService personService;
    @Resource
    private ProjectOfPersonService projectOfPersonService;
    @Resource
    private DetailsService detailsService;
    @Resource
    private DemandService demandService;
    @Resource
	private CustomerService customerService;
    @Autowired
	private SubscribeService subscribeService;

    private void addAttrModel(Model model) {
        // 项目状态
        List<Dictiontry> projectStatusDictiontryList = SystemGlobals.getInstance()
                .getDictiontryMap(Constant.DICTIONTRY_PROJECTSTATUS);
        // 项目来源
        List<Dictiontry> projecSourcetDictiontryList = getProjectSorce();
        // 项目类型
        List<Dictiontry> projectTypeDictiontryList = SystemGlobals.getInstance()
                .getDictiontryMap(Constant.DICTIONTRY_PROJECTTYPE);
        // 专家类型
        List<Dictiontry> personTypeDictiontryList = getPersonType();
        // 人才级别
        List<Dictiontry> talentLevelDictiontryList = getTalentLevel();
        //所有国家
        List<Dictiontry> countryDictiontryList = SystemGlobals.getInstance()
                .getDictiontryMap(Constant.DICTIONTRY_COUNTRY);
        // 所有省份
        List<Dictiontry> provinceDictiontryList = getAreaProvince();
        // 研究领域
        List<Dictiontry> researchFieldDictiontryList = getResearchField();
        //技术成熟度
        List<Dictiontry> technicalDictiontryList = SystemGlobals.getInstance()
                .getDictiontryMap(Constant.DICTIONTRY_PROJECTTECHNICAL);

        model.addAttribute("projectStatusDictiontryList", projectStatusDictiontryList);
        model.addAttribute("projecSourcetDictiontryList", projecSourcetDictiontryList);
        model.addAttribute("projectTypeDictiontryList", projectTypeDictiontryList);
        model.addAttribute("personTypeDictiontryList", personTypeDictiontryList);
        model.addAttribute("talentLevelDictiontryList", talentLevelDictiontryList);
        model.addAttribute("countryDictiontryList", countryDictiontryList);
        model.addAttribute("provinceDictiontryList", provinceDictiontryList);
        model.addAttribute("researchFieldDictiontryList", researchFieldDictiontryList);
        model.addAttribute("technicalDictiontryList", technicalDictiontryList);
    }

    /**
     * 添加项目
     * @author pdz
     * @date 2018年8月16日
     * @param model
     * @return
     */
    @RequestMapping("/showAdd")
    public String showAdd(Model model) {
        addAttrModel(model);
        return "project/showAdd";
    }
    
    /**
     * 添加项目及项目属性
     * 
     * @param project
     * @param projectAttr
     * @return
     */
    @RequestMapping("/add")
    public String add(@Valid Project project, BindingResult bindingResult, ProjectAttr projectAttr,
            HttpServletRequest request, Model model, MultipartFile file) {
        if (bindingResult.hasErrors()) {
            List<FieldError> list = bindingResult.getFieldErrors();
            list.forEach(e -> logger.error("错误字段：{}, 错误信息：{}", e.getField(), e.getDefaultMessage()));
            list.forEach(e -> model.addAttribute(e.getField(), e.getDefaultMessage()));
            return showAdd(model);
        }
        setProjectAttr(project, projectAttr, request);

        projectService.save(project, projectAttr, file);
        addProjectIsolr(project, projectAttr, new SolrOperation<>());
        return "redirect:/project/showDetail?projectId="+project.getPid();
    }

    /**
     * 给Project和ProjectAttr设置一些必需的属性
     * @author pdz
     * @date 2018年9月5日
     * @param project
     * @param projectAttr
     * @param request
     */
    private void setProjectAttr(Project project, ProjectAttr projectAttr, HttpServletRequest request) {
        String projectId = StrUtil.getUUID32();
        project.setPid(projectId);
        project.setCollectPersonId(getUserId(request));
        project.setEntryTime(StrUtil.getCurrentDateTime());
        project.setProjectTypeInteger(StrUtil.stringByByte(project.getProjectType()));
        project.setResearchFieldInteger(StrUtil.stringByByte(project.getResearchField()));

        String projectAttrId = StrUtil.getUUID32();
        projectAttr.setPid(projectAttrId);
        projectAttr.setProjectId(projectId);
    }

    /**
     * 修改项目页面只能修改未关联到person表的持有人,如果没有未关联的持有人，页面文本框显示为空
     * @author pdz
     * @date 2018年8月20日
     * @param model
     * @param projectId
     * @return
     */
    @RequestMapping("/showUpdate")
    public String showUpdate(Model model, String projectId) {
        // 根据id查询项目用于回显
        Project project = projectService.getById(projectId);
        List<Person> holderList = personService.queryHolders(projectId);
        List<String> holderNameList = holderList.stream().map(Person::getName).collect(Collectors.toList());
        String projectHolder = project.getProjectHolder() == null ? "" : project.getProjectHolder();
        //未关联person表的持有人
        String unConnedHolder = Stream.of(projectHolder.split(","))
                .filter(name -> !holderNameList.contains(name)).collect(Collectors.joining(","));
        //只在项目修改页面显示未关联person的持有人
        project.setProjectHolder(unConnedHolder);
        String[] projectTypeArr = StrUtil.byteToString(project.getProjectType()).split(",");
        String[] researchFieldArr = StrUtil.byteToString(project.getResearchField()).split(",");

        ProjectAttr projectAttr = projectAttrService.findByProjectId(projectId);
        areaModel(model, project.getArea(), project.getDomesticOrForeign());
        addAttrModel(model);
        model.addAttribute("project", project);
        model.addAttribute("projectTypeArr", projectTypeArr);
        model.addAttribute("researchFieldArr", researchFieldArr);
        model.addAttribute("projectAttr", projectAttr);
        return "project/showUpdate";
    }
    
    @RequestMapping("/showUpdateOverRide")
    public String showUpdateOverRide(Model model, String projectId,@RequestParam(value = "origType", required = false) String origType,@RequestParam(value = "conferencePid", required = false) String conferencePid) {
    	model.addAttribute("origType", origType);
    	model.addAttribute("conferencePid", conferencePid);
    	return showUpdate(model, projectId);
    }

    @Log("修改项目")
    @RequestMapping("/update")
    public String update(@Valid Project project, BindingResult bindingResult, ProjectAttr projectAttr, @RefPid String proId,
            String proAttrId, String connedHolder, Model model,@RequestParam(value = "origType", required = false) String origType,
            @RequestParam(value = "conferencePid", required = false) String conferencePid, MultipartFile file) {
        if (bindingResult.hasErrors()) {
            List<FieldError> list = bindingResult.getFieldErrors();
            list.forEach(e -> logger.error("错误字段：{}, 错误信息：{}", e.getField(), e.getDefaultMessage()));
            list.forEach(e -> model.addAttribute(e.getField(), e.getDefaultMessage()));
            return showUpdate(model, proId);
        }
        project.setPid(proId);
//        String projectHolder = (connedHolder + "," + project.getProjectHolder());
        String projectHolder = project.getProjectHolder();
        projectHolder = projectHolder.startsWith(",") ? projectHolder.replaceFirst(",", "") : projectHolder;
        project.setProjectHolder(projectHolder);
        project.setProjectTypeInteger(StrUtil.stringByByte(project.getProjectType()));
        project.setResearchFieldInteger(StrUtil.stringByByte(project.getResearchField()));
        project.setUpdateTime(StrUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss"));
        projectAttr.setPid(proAttrId);
        projectAttr.setProjectId(proId);
        projectService.update(project, projectAttr, file);
        updateProjectIsolr(project, projectAttr, new SolrOperation<>(), false);
        //判断跳转来源 by xyx
        if(StringUtil.isNotEmpty(origType)){
        	return "redirect:/conference/showDetail?conferenceId=" + conferencePid;
        }
        return "redirect:/project/showDetail?projectId="+proId;
    }

    /**
     * 添加项目持有人页面
     * 
     * @author pdz
     * @date 2018年8月14日
     * @param model
     * @param projectId
     * @return
     */
    @RequestMapping("/showAddHolder")
    public String showAddHolder(Model model, String projectId) {
        addAttrModel(model);
        model.addAttribute("projectId", projectId);
        return "project/showAddHolder";
    }

    /**
     * 添加项目持有人
     * 
     * @author pdz
     * @date 2018年8月14日
     * @holderName 没有关联的持有人的名字
     * @return
     */
    @RequestMapping(value = "/addHolder")
    public String addHolder(@Valid Person person, BindingResult bindingResult, HttpServletRequest request,
            String projectId, Model model, MultipartFile file, String holderName) {
        if (bindingResult.hasErrors()) {
            List<FieldError> list = bindingResult.getFieldErrors();
            list.forEach(e -> logger.error("错误字段：{}, 错误信息：{}", e.getField(), e.getDefaultMessage()));
            list.forEach(e -> model.addAttribute(e.getField(), e.getDefaultMessage()));
            return showAddHolder(model, projectId);
        }
        if (!hasContact(person)) {
            model.addAttribute("fixedPhone", "至少填写一种联系方式");
            return showAddHolder(model, projectId);
        }
        setPersonAttr(person, request);
        Project project = projectService.getById(projectId);
        personService.addHolder(person, project, file);
        addPersonIsolr(person, new SolrOperation<>());
        updateProjectIsolr(project, null, new SolrOperation<>(), true);
        //修改没有关联的持有人，且修改了名字，就把原来的没有关联的持有人删掉
        if (StringUtil.isNotEmpty(holderName) && !person.getName().trim().equals(holderName)) {
        	return deleteHolder(model, projectId, null, holderName);
        }
        return "redirect:/project/showHolders?projectId=" + projectId;
    }

    /**
     * 设置person的一些必需属性
     * @author pdz
     * @date 2018年9月5日
     * @param person
     * @param request
     */
    private void setPersonAttr(Person person, HttpServletRequest request) {
        person.setPid(StrUtil.getUUID32());
        person.setCollectPersonId(getUserInfoBySession(request).getUserId());
        person.setEntryTime(StrUtil.getCurrentDateTime());
        person.setResearchFieldInteger(StrUtil.stringByByte(person.getResearchField()));
        if (StringUtil.isNotEmpty(person.getTalentLevel())) {
			person.setTalentLevelInteger(StrUtil.stringByByte(person.getTalentLevel()));
		}
    }

    /**
     * 修改联系人，只能修改已经关联了person的联系人，只有名字的在项目修改页面修改
     * 
     * @author pdz
     * @date 2018年8月14日
     * @param model
     * @param projectContactId
     * @return
     */
    @RequestMapping("/showUpdateContact")
    public String showUpdateContact(Model model, String projectContactId, HttpServletRequest request) {
        if (!projectContactId.matches("[a-z0-9]{32}")) {
            model.addAttribute("projectContactNotExists", "没有关联的联系人，不能修改");
            return showQuery(model, 1, request);
        }
        Person person = personService.getById(projectContactId);
        String[] researchFieldArr = StrUtil.byteToString(person.getResearchField()).split(",");
        String[] talentLevelArr = new String[0];
        if (StringUtil.isNotEmpty(person.getTalentLevel())) {
			talentLevelArr = StrUtil.byteToString(person.getTalentLevel()).split(",");
		}
        areaModel(model, person.getArea(), person.getDomesticOrForeign());
        addAttrModel(model);
        model.addAttribute("person", person);
        model.addAttribute("researchFieldArr", researchFieldArr);
        model.addAttribute("talentLevelArr", talentLevelArr);
        return "project/showUpdateContact";
    }
    
    /**
     * 修改联系人
     * 
     * @author pdz
     * @date 2018年8月14日
     * @person 页面传入的
     * @return
     */
    @RequestMapping("/updateContact")
    public String updateContact(@Valid Person person, BindingResult bindingResult, Model model, MultipartFile file, 
    		HttpServletRequest request, String projectId) {
        if (bindingResult.hasErrors()) {
            List<FieldError> list = bindingResult.getFieldErrors();
            list.forEach(e -> logger.error("错误字段：{}, 错误信息：{}", e.getField(), e.getDefaultMessage()));
            list.forEach(e -> model.addAttribute(e.getField(), e.getDefaultMessage()));
            return showUpdateContact(model, person.getPid(), request);
        }
        String oldName = personService.getById(person.getPid()).getName();
        if (!hasContact(person)) {
            model.addAttribute("fixedPhone", "至少填写一种联系方式");
            return showUpdateContact(model, person.getPid(), request);
        } else if(!person.getName().equals(oldName)) {
        	//如果名字改变了，数据库中存在该名字会在页面弹出，否则就是新增一个联系人
        	person.setExpertNumber(null);
        	return addContact(person, bindingResult, projectId, request, model, file);
        }
        person.setResearchFieldInteger(StrUtil.stringByByte(person.getResearchField()));
        if (StringUtil.isNotEmpty(person.getTalentLevel())) {
			person.setTalentLevelInteger(StrUtil.stringByByte(person.getTalentLevel()));
		}
        personService.update(person, file);
        updatePersonIsolr(person, new SolrOperation<>(), false);
        return "redirect:/project/showQuery";
    }

    /**
     * 修改持有人，如果持有人未关联项目，实际是添加持有人
     * @author pdz
     * @date 2018年8月14日
     * @param model
     * @param projectId
     * @return
     */
    @RequestMapping("/showUpdateHolder")
    public String showUpdateHolder(Model model, String personId, String projectId) {
        Person holder = personService.getById(personId);
        String[] researchFieldArr = StrUtil.byteToString(holder.getResearchField()).split(",");
        String[] talentLevelArr = new String[0];
        if (StringUtil.isNotEmpty(holder.getTalentLevel())) {
        	talentLevelArr = StrUtil.byteToString(holder.getTalentLevel()).split(",");
        }
        addAttrModel(model);
        areaModel(model, holder.getArea(), holder.getDomesticOrForeign());
        model.addAttribute("holder", holder);
        model.addAttribute("researchFieldArr", researchFieldArr);
        model.addAttribute("talentLevelArr", talentLevelArr);
        model.addAttribute("projectId", projectId);
        return "project/showUpdateHolder";
    }
    
    /**
     * 修改项目持有人
     * 
     * @author pdz
     * @date 2018年8月14日
     * @return
     */
    @RequestMapping("/updateHolder")
    public String updateHolder(@Valid Person person, BindingResult bindingResult, Model model, String projectId,
    		MultipartFile file, HttpServletRequest request) {
        if (bindingResult.hasErrors()) {
            List<FieldError> list = bindingResult.getFieldErrors();
            list.forEach(e -> logger.error("错误字段：{}, 错误信息：{}", e.getField(), e.getDefaultMessage()));
            list.forEach(e -> model.addAttribute(e.getField(), e.getDefaultMessage()));
            return showUpdateHolder(model, person.getPid(), projectId);
        }
        String oldName = personService.getById(person.getPid()).getName();
        if (!hasContact(person)) {
            model.addAttribute("fixedPhone", "至少填写一种联系方式");
            return showUpdateHolder(model, person.getPid(), projectId);
        } else if (!oldName.equals(person.getName())) {
        	//修改了名字，如果数据库中有同名的会弹出，否则就是添加持有人
        	person.setExpertNumber(null);
        	return addHolder(person, bindingResult, request, projectId, model, file, null);
        }
        person.setResearchFieldInteger(StrUtil.stringByByte(person.getResearchField()));
        if (StringUtil.isNotEmpty(person.getTalentLevel())) {
			person.setTalentLevelInteger(StrUtil.stringByByte(person.getTalentLevel()));
		}
        personService.updateHolder(person, file);
        updatePersonIsolr(person, new SolrOperation<>(), false);
        return "redirect:/project/showHolders?projectId=" + projectId;
    }
    
    @RequestMapping("/deleteHolder")
    public String deleteHolder(Model model, String projectId, String personId, String holderName) {
        if (StringUtil.isNotEmpty(personId)) {
			projectOfPersonService.deleteByProjectIdAndPersonId(projectId, personId);
		}
        //把project中持有人字段的名字也删除
        Project project = projectService.getById(projectId);
        String projectHolder = project.getProjectHolder();
        if (StringUtil.isNotEmpty(projectHolder) && StringUtil.isNotEmpty(holderName)) {
            projectHolder = projectHolder.replaceFirst(holderName, "");
            projectHolder = Stream.of(projectHolder.split(",")).filter(StringUtil::isNotEmpty).collect(Collectors.joining(","));
            project.setProjectHolder(projectHolder);
            projectService.updateProjectHolder(project);
            updateProjectIsolr(project, null, new SolrOperation<>(), true);
        }
        return "redirect:/project/showHolders?projectId=" + projectId;
    }

    /**
     * 添加项目联系人页面
     * @author pdz
     * @date 2018年8月14日
     * @param model
     * @param projectId
     * @return
     */
    @RequestMapping("/showAddContact")
    public String showAddContact(Model model, String projectId) {
        addAttrModel(model);
        return "project/showAddContact";
    }

    /**
     * 添加项目联系人
     * @author pdz
     * @date 2018年8月14日
     * @person 页面传入的
     * @return
     */
    @RequestMapping("/addContact")
    public String addContact(@Valid Person person, BindingResult bindingResult, String projectId, 
            HttpServletRequest request, Model model, MultipartFile file) {
        if (bindingResult.hasErrors()) {
            List<FieldError> list = bindingResult.getFieldErrors();
            list.forEach(e -> logger.error("错误字段：{}, 错误信息：{}", e.getField(), e.getDefaultMessage()));
            list.forEach(e -> model.addAttribute(e.getField(), e.getDefaultMessage()));
            return showAddContact(model, projectId);
        }
        if (!hasContact(person)) {
            model.addAttribute("fixedPhone", "至少填写一种联系方式");
            return showAddContact(model, projectId);
        }
        setPersonAttr(person, request);
        Project project = projectService.getById(projectId);
        personService.addContact(person, project, file);
        addPersonIsolr(person, new SolrOperation<>());
        updateProjectIsolr(project, null, new SolrOperation<>(), true);
        return "redirect:/project/showQuery";
    }

    @RequestMapping("/showHolders")
    public String showHolders(String projectId, @RequestParam(defaultValue = "1") int pageNo, Model model) {
        PageHelper.startPage(pageNo, 10);
        List<Person> holderList = holderList(projectId);
        PageInfo<Person> pageInfo = new PageInfo<Person>(holderList);
        model.addAttribute("holderList", holderList);
        model.addAttribute(pageInfo);
        model.addAttribute("projectId", projectId);
        return "project/showHolders";
    }

	private List<Person> holderList(String projectId) {
		Project project = projectService.getById(projectId);
		List<Person> holderList = personService.queryHolders(projectId);
        String projectHolder = project.getProjectHolder();
        if (StringUtil.isNotEmpty(projectHolder)) {
            List<Person> list = Stream.of(projectHolder.split(",")).filter(name -> !containsName(holderList, name))
                    .map(name -> new Person(name)).collect(Collectors.toList());
            holderList.addAll(list);
        }
		return holderList;
	}

    private boolean containsName(List<Person> holderList, String name) {
        if (holderList.isEmpty()) {
			return false;
		}
        return holderList.stream().anyMatch(person -> person.getName().equals(name));
    }
    
    /**
     * 查询项目分页
     * @param model
     * @return
     */
    @RequestMapping("/showQuery")
    public String showQuery(Model model, @RequestParam(defaultValue = "1") int pageNo, HttpServletRequest request) {
        pageInfo(model, pageNo, new Project(), request);
        return "project/showQuery";
    }

    /**
     * 查询分页
     * @author pdz
     * @date 2018年8月29日
     * @param model
     * @param pageNo
     * @param pro
     * @return
     */
    private PageInfo<Project> pageInfo(Model model, int pageNo, Project pro, HttpServletRequest request) {
        PageHelper.startPage(pageNo, DEFAULT_COUNT);
        List<Project> list = projectService.queryAll(pro);
        PageInfo<Project> pageInfo = new PageInfo<Project>(list);
        pageInfo.getList().forEach(project -> project.setProjectType(getDicCheckboxWorth(project.getProjectType(), Constant.DICTIONTRY_PROJECTTYPE)));
        pageInfo.getList().forEach(project -> project.setProjectStatusWorth(getDicSingleWorth(project.getProjectStatus(), Constant.DICTIONTRY_PROJECTSTATUS)));
        //查询已经关注的
        Subscribe subscribe = new Subscribe();
        subscribe.setSubType(1);//关注类型为项目
        subscribe.setUserid(getUserId(request));
        List<Subscribe> subList = subscribeService.queryAll(subscribe);
        List<String> subProjectIdList = subList.stream().map(Subscribe::getTypeObject).collect(Collectors.toList());
        model.addAttribute("subProjectIdList", subProjectIdList);
        addAttrModel(model);
        model.addAttribute(pageInfo);
        return pageInfo;
    }

	@RequestMapping("/showConditionQuery")
    public String showConditionQuery(Model model, Project project, String searchKeyword, @RequestParam(defaultValue = "1") int pageNo, 
    		Integer personType, HttpServletRequest request) {
        searchPageInfo(model, project, searchKeyword, pageNo, request);
        return "project/showQuery";
    }

    /**
     * 根据搜索条件查询分页
     * @author pdz
     * @date 2018年8月29日
     * @param model
     * @param project
     * @param searchKeyword
     * @param pageNo
     * @param personType 1为联系人，2为持有人
     * @return
     */
    private PageInfo<Project> searchPageInfo(Model model, Project project, String searchKeyword, int pageNo, HttpServletRequest request) {
        if (StringUtil.isEmpty(searchKeyword) && StrUtil.isEmpty(project)) {//判断是否为空对象，不要往project中的per属性中传值
            return pageInfo(model, pageNo, project, request);
        }
        if (StringUtil.isNotEmpty(searchKeyword)) {
        	searchKeyword = searchKeyword.trim();
            if (searchKeyword.matches("R\\d{6,}")) {
				project.setProjectNumber(Integer.parseInt(searchKeyword.replaceFirst("R", "")));
			} else {
				if (project.getPersonType() == null)
					project.setProjectName(searchKeyword);
				else {
					project.setPer(new Person(searchKeyword));
				}
			}
        }
        String[] researchFieldArr = null;
        String[] projectTypedArr = null;
        if (StringUtil.isNotEmpty(project.getProjectType())) {
            projectTypedArr = project.getProjectType().split(",");
            project.setProjectTypeNumber(projectTypedArr.length);
            project.setProjectTypeInteger(StrUtil.stringByByte(project.getProjectType()));
        }
        if (StringUtil.isNotEmpty(project.getResearchField())) {
            researchFieldArr = project.getResearchField().split(",");
            project.setResearchFieldNumber(researchFieldArr.length);
            project.setResearchFieldInteger(StrUtil.stringByByte(project.getResearchField()));
        }
        model.addAttribute("searchKeyword", searchKeyword);
        model.addAttribute("project", project);
        model.addAttribute("researchFieldArr", researchFieldArr);
        model.addAttribute("projectTypedArr", projectTypedArr);
        if (project.getArea() != null) {
			areaModel(model, project.getArea(), project.getDomesticOrForeign());
		}
        PageInfo<Project> pageInfo = pageInfo(model, pageNo, project, request);
        return pageInfo;
    }
    
    /**
     * 转到项目匹配页面
     * @param model
     * @param demand
     * @return
     */
    @RequestMapping("/showDemandMatchedProject")
    public String showDemandMatchedProject(Model model, Demand demand, HttpServletRequest request, @RequestParam(value = "customerId", required = false) String customerId) {
    	searchMatchedProject(model, null, null, null, null, 1, demand.getPid(), request, customerId);
        return "project/showDemandMatchedProject";
    }
    
	@RequestMapping("/searchMatchedProject")
    public String searchMatchedProject(Model model, String researchField, String area, String searchKeyword, Integer domesticOrForeign, @RequestParam(defaultValue = "1") int pageNo, 
    		String demandId, HttpServletRequest request,@RequestParam(value = "customerId", required = false) String customerId) {
    	
    	String researchFieldWorth = StringUtil.isEmpty(researchField) ? null : getDicCheckboxWorth(StrUtil.stringByByte(researchField).toString(), Constant.DICTIONTRY_DEMANDFIELD);
    	String areaWorth = StringUtil.isEmpty(area) ? null : getAreaWorth(area, domesticOrForeign);
    	Demand demand = demandService.getById(demandId);
    	demand.setDemandType(getDicCheckboxWorth(demand.getDemandType(), Constant.DICTIONTRY_DEMANDTYPE));
        Pagination pagination = new SolrOperation<>().queryList(pageNo, DEFAULT_COUNT, 6, demandId, researchFieldWorth, areaWorth, searchKeyword);
        ButtDetails buttDetails = new ButtDetails();
        buttDetails.setButtPersonId(getUserId(request));
        buttDetails.setDemandNumber(demandId);
        buttDetails.setFuture(1);
        buttDetails.setProjectNumberEmpty(false);
        List<ButtDetails> detailList = detailsService.findButtDetails(buttDetails);
        List<String> buttedProjectIdList = detailList.stream().map(ButtDetails::getProjectNumber).distinct().collect(Collectors.toList());
        String[] researchFieldArr = StringUtil.isNotEmpty(researchField) ? researchFieldArr = researchField.split(",") : new String[0];
        if (StringUtil.isNotEmpty(area))
            areaModel(model, area, domesticOrForeign);
        addAttrModel(model);
        model.addAttribute("demand", demand);
        model.addAttribute("researchFieldArr", researchFieldArr);
        model.addAttribute("pageInfo", pagination);
        model.addAttribute("buttedProjectIdList", buttedProjectIdList);
        model.addAttribute("domesticOrForeign", domesticOrForeign);
        
        if (StringUtil.isNotEmpty(customerId)) {
        	Customer customer = customerService.getById(customerId);
        	model.addAttribute("customer", customer);
        	model.addAttribute("customerId", customerId);
        }
        return "project/showDemandMatchedProject";
    }
    
    @RequestMapping("/demandMatchProject")
    @ResponseBody
    public String demandMatchProject(String demandId, Demand demand, String projectId, Project project, HttpServletRequest request) {
        demand.setPid(demandId);
        project.setPid(projectId);
        detailsService.addFirstButtDetails(project, demand, null, null, null, getUserId(request));
        return "success";
    }

    /**
     * 某个项目的需求对接列表
     * @author pdz
     * @date 2018年9月12日
     * @param projectId
     * @param request
     * @param model
     * @param buttSta 状态没有值就查询所有状态
     * @param pageNo
     * @return
     */
	@RequestMapping("/showDemandButtDetail")
    public String showDemandButtDetail(Project project, HttpServletRequest request, Model model, Integer buttSta, @RequestParam(defaultValue = "1") int pageNo) {
    	PageHelper.startPage(pageNo, DEFAULT_COUNT);
        List<ButtDetails> demandDetailList = queryDemandButtDetail(project.getPid(), request, buttSta);
        PageInfo<ButtDetails> pageInfo = new PageInfo<ButtDetails>(demandDetailList);
        List<Dictiontry> buttStatusList=SystemGlobals.getInstance().getDictiontryMap(Constant.DICTIONTRY_BUTTSTATUS);
        model.addAttribute("buttStatusList", buttStatusList);
        model.addAttribute("pageInfo", pageInfo);
        model.addAttribute("project", project);
        model.addAttribute("buttSta", buttSta != null ? buttSta.toString() : "");
        //已经更新过对接详情的所有需求ID
        List<String> updatedDemandIdList = queryButtDemand(project.getPid(), null, bd -> bd.setFuture(0), null)
        		.stream().map(ButtDetails::getDemandNumber).distinct().collect(Collectors.toList());
        List<String> undoButtIdList = pageInfo.getList().stream().filter(bd -> bd.getButtPersonId().equals(getUserId(request)))
        		.filter(bd -> !updatedDemandIdList.contains(bd.getDemandNumber())).map(ButtDetails::getPid).collect(Collectors.toList());
        model.addAttribute("undoButtIdList", undoButtIdList);
        return "project/showDemandButtDetail";
    }

    /**
     *  返回项目需求对接列表
     * @param projectId 项目id
     * @param request
     * @param buttSta 状态数字值，如果为空查询所有状态
     * @param pageNo
     * @return
     */
    @ResponseBody
    @RequestMapping("/queryDemandButtDetail")
	public List<ButtDetails> queryDemandButtDetail(String projectId, HttpServletRequest request, Integer buttSta) {
        List<ButtDetails> demandDetailList = queryButtDemand(projectId, buttSta, bd -> bd.setFuture(1), null);
        demandDetailList.forEach(bd -> bd.setButtStatusWorth(getButtStatusWorth(bd.getButtStatus())));
        demandDetailList.forEach(bd -> bd.setRemark2((bd.getProjectName() + "<br>" + bd.getDemandName())));
		return demandDetailList;
	}

	private List<ButtDetails> queryButtDemand(String projectId, Integer buttSta, Consumer<ButtDetails> futureAction, Consumer<ButtDetails> buttPersonAction) {
		ButtDetails buttDetails = new ButtDetails();
        buttDetails.setProjectNumber(projectId);
        if (futureAction != null)
        	futureAction.accept(buttDetails);
        if (buttPersonAction != null)
        	buttPersonAction.accept(buttDetails);
        buttDetails.setButtStatus(buttSta);
        buttDetails.setDemandNumberEmpty(false);
        List<ButtDetails> demandDetailList = detailsService.findButtDetails(buttDetails);
		return demandDetailList;
	}
    
    @RequestMapping("/deleteDemandButt")
    public String deleteDemandButt(Project project, HttpServletRequest request, Model model, Integer buttSta, 
    		@RequestParam(defaultValue = "1") int pageNo, String buttId) {
    	detailsService.delete(buttId);
    	return showDemandButtDetail(project, request, model, buttSta, pageNo);
    }
    
    /**
     * 下载项目已经匹配的需求
     * @author pdz
     * @date 2018年10月31日
     * @param projectId 项目ID
     */
    @RequestMapping("/downButtedDemand")
    public void downButtedDemand(String projectId, HttpServletRequest request, HttpServletResponse response) {
    	List<String> tagList = Arrays.asList("需求ID", "需求名称", "需求类型", "需求状态", "需求内容", "所属领域", "需求联系人", "手机", "邮箱");
    	List<Demand> buttedProjectList = projectService.queryButtedDemand(projectId);
    	List<List<String>> contentLists = buttedProjectList.stream().map(dem -> createContentList(dem)).collect(Collectors.toList());
    	File excelFile = ExcelUtil.writeExcel(tagList, contentLists, StrUtil.getCurrentDateTime("yyyyMMddHHmmss") + "-project-butted-demands.xls");
    	try {
			ExcelUtil.downLoad(request, excelFile, response);
		} catch (Exception e) {
			e.printStackTrace();
		}
    }
    
    private List<String> createContentList(Demand dem) {
    	if (dem.getPer() == null)//联系人可能不存在
    		dem.setPer(new Person());
		return Arrays.asList("D"+dem.getDemandNumber(), dem.getDemandName(), getDicCheckboxWorth(dem.getDemandType(), Constant.DICTIONTRY_DEMANDTYPE),
				getDicSingleWorth(dem.getDemandStatus(), Constant.DICTIONTRY_DEMANDSTATUS), dem.getDemandContent(),
				getDicCheckboxWorth(dem.getResearchField(), Constant.DICTIONTRY_DEMANDFIELD),
				dem.getPer().getName(), dem.getPer().getTell(), dem.getPer().getEmail());
	}

	/**
     * 某个项目的客户对接列表
     * @author pdz
     * @date 2018年9月12日
     * @param projectId
     * @param request
     * @param model
     * @param buttSta
     * @param pageNo
     * @return
     */
    @RequestMapping("/showCustomerButtDetail")
    public String showCustomerButtDetail(String projectId, HttpServletRequest request, Model model, Integer buttSta, @RequestParam(defaultValue = "1") int pageNo) {
        PageHelper.startPage(pageNo, DEFAULT_COUNT);
        List<ButtDetails> customerDetailList = queryCustomerButtDetail(projectId, request, buttSta);
        PageInfo<ButtDetails> pageInfo = new PageInfo<ButtDetails>(customerDetailList);
        pageInfo.getList().forEach(bd -> bd.setButtStatusWorth(getButtStatusWorth(bd.getButtStatus())));
        
        List<Dictiontry> buttStatusList=SystemGlobals.getInstance().getDictiontryMap(Constant.DICTIONTRY_BUTTSTATUS);
        model.addAttribute("buttStatusList", buttStatusList);
        model.addAttribute("pageInfo", pageInfo);
        model.addAttribute("projectId", projectId);
        model.addAttribute("buttSta", buttSta != null ? buttSta.toString() : "");
        model.addAttribute("showButtDetailUrl", "/project/showCustomerButtDetail");
        return "project/showProjectButtedDetail";
    }

    @ResponseBody
    @RequestMapping("/queryCustomerButtDetail")
	public List<ButtDetails> queryCustomerButtDetail(String projectId, HttpServletRequest request, Integer buttSta) {
		ButtDetails buttDetails = new ButtDetails();
        buttDetails.setProjectNumber(projectId);
        buttDetails.setFuture(1);
        buttDetails.setButtStatus(buttSta);
        buttDetails.setCustomerNumberEmpty(false);
        List<ButtDetails> customerDetailList = detailsService.findButtDetails(buttDetails);
        customerDetailList.forEach(bd -> bd.setButtStatusWorth(getButtStatusWorth(bd.getButtStatus())));
        customerDetailList.forEach(bd -> bd.setRemark2(bd.getProjectName() + "<br>" + bd.getCustomerName()));
		return customerDetailList;
	}
    
    @SuppressWarnings("unchecked")
    @ResponseBody
	@RequestMapping("/notButtDemand")
    public List<LuceneDemand> notButtDemand(String projectId, HttpServletRequest request) {
    	Pagination pagination = new SolrOperation<>().queryList(1, 10, 4, projectId);
    	pagination = pagination == null ? new Pagination() : pagination; 
    	List<LuceneDemand> list = pagination.getList();
    	List<ButtDetails> demandButtDetailList = queryDemandButtDetail(projectId, request, null);
    	//将已经匹配的demandId设为null，在页面判断
    	List<String> demandIdDetailList = demandButtDetailList.stream().map(ButtDetails::getDemandNumber).collect(Collectors.toList());
    	list.stream().filter(ld -> demandIdDetailList.contains(ld.getDemandId())).forEach(ld -> ld.setDemandId(null));
    	return list;
    }
    
    @SuppressWarnings("unchecked")
    @ResponseBody
    @RequestMapping("/notButtCustomer")
    public List<LuceneCustomer> notButtCustomer(String projectId, HttpServletRequest request) {
    	Pagination pagination = new SolrOperation<>().queryList(1, 10, 5, projectId);
    	List<LuceneCustomer> list = pagination.getList();
    	List<ButtDetails> customerButtDetailList = queryCustomerButtDetail(projectId, request, null);
    	//将已经匹配的customerId设为null，在页面判断
    	list.stream().filter(lc -> customerButtDetailList.stream().map(ButtDetails::getCustomerNumber).anyMatch(cusId -> cusId.equals(lc.getCustomerId())))
    		.forEach(lc -> lc.setCustomerId(null));
    	return list;
    }
    
    @RequestMapping("/importProject")
    public String importProject(Model model, MultipartFile file, HttpServletRequest request, HttpServletResponse response) {
        if (file != null) {
            try(InputStream in = file.getInputStream()) {
                List<ImportProject> importProjectList = ExcelUtil.readImportProjectList(in);
                //录入人
                User user = new User();
                user.setFullName(importProjectList.get(0).getProject().getCollectPersonId());
				String userId = userService.queryAll(user).get(0).getPid();
				//联系人
				List<Integer> expertNumberList = importProjectList.stream()
					.map(ip -> ip.getProject().getProjectContactId()).filter(StringUtil::isNotEmpty)
					.map(Integer::parseInt).collect(Collectors.toList());
				List<Person> personList = personService.queryInExpertNumber(expertNumberList);
				List<List<String>> contentLists = new ArrayList<>(importProjectList.size());
				
				List<String> projectNameList = projectService.queryAll(new Project()).stream().map(Project::getProjectName).collect(Collectors.toList());
                importProjectList.forEach(ip -> importData(ip, userId, personList, contentLists, projectNameList, request));
                List<String> tagList = Arrays.asList("专家ID", "专家姓名", "项目ID", "项目名称");
                File excelFile = ExcelUtil.writeExcel(tagList, contentLists, "back.xls");
                ExcelUtil.downLoad(request, excelFile, response);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return showQuery(model, 1, request);
    }

    //导入的同时如果不修改索引，则导入后一起改
	private void importData(ImportProject ip, String userId, List<Person> personList, List<List<String>> contentLists, List<String> projectNameList, HttpServletRequest request) {
		List<String> contentList = new ArrayList<>();
        Project project = ip.getProject();
        //如果名字相同就不导入
        if (projectNameList.contains(project.getProjectName()))
        	return;
        ProjectAttr projectAttr = ip.getProjectAttr();
        setProjectAttr(project, projectAttr, request);
        project.setCollectPersonId(userId);
        
        Person person = ip.getPerson();
        setPersonAttr(person, request);
        if (StringUtil.isNotEmpty(project.getProjectContactId())) {
        	contentList.add("E"+project.getProjectContactId());
        	contentList.add(person.getName());
        	Optional<Person> personOpt = personList.stream().filter(per -> per.getExpertNumber().toString().equals(project.getProjectContactId())).findAny();
        	if (personOpt.isPresent())
        		project.setProjectContactId(personOpt.get().getPid());
        	else
        		project.setProjectContactId(null);
        	
        	projectService.importData(project, pro -> {
        		projectService.save(pro, projectAttr, null);
//        		addProjectIsolr(pro, projectAttr, new SolrOperation<>());
        		if (person.getName().equals(project.getProjectHolder()) && StringUtil.isNotEmpty(project.getProjectContactId())) {
        			project.setProjectHolder(null);//project中的持有人字段只保存没有关联的持有人
        			linkHolder(pro.getProjectContactId(), pro.getPid());
        		}
        	});
		} else {
			projectService.importData(project, pro -> {
				projectService.save(pro, projectAttr, null);
//				addProjectIsolr(pro, projectAttr, new SolrOperation<>());
				personService.addContact(person, pro, null);
//				addPersonIsolr(person, new SolrOperation<>());
//		        updateProjectIsolr(project, null, new SolrOperation<>(), false);
		        
				if (person.getName().equals(project.getProjectHolder())) {
					personService.addHolder(person, pro, null);
//					addPersonIsolr(person, new SolrOperation<>());
//			        updateProjectIsolr(project, null, new SolrOperation<>(), false);
				}
			});
	        contentList.add("E"+person.getExpertNumber());
	        contentList.add(person.getName());
		}
        contentList.add("R"+project.getProjectNumber());
        contentList.add(project.getProjectName());
        contentLists.add(contentList);
        
        //如果项目持有人和联系人相同也将持有人关联起来
//        if (project.getProjectHolder().equals(person.getName()))
//            projectService.importData(project, projectAttr, pro -> personService.addContact(person, pro, null), pro -> personService.addHolder(person, pro, null));
//        else
//            projectService.importData(project, projectAttr, pro -> personService.addContact(person, pro, null), null);
    }
    
    @RequestMapping("/showDetail")
    public String showDetail(String projectId, Model model, String demandId, Integer lookExpert, String expertId, String lookPwd, HttpServletRequest request) {
        Project project = projectService.getById(projectId);
        ProjectAttr projectAttr = projectAttrService.findByProjectId(projectId);
        project.setSourceWorth(getDicSingleWorth(project.getSourceId(), Constant.DICTIONTRY_PROJECTSOURCE));
        project.setProjectStatusWorth(getDicSingleWorth(project.getProjectStatus(), Constant.DICTIONTRY_PROJECTSTATUS));
        project.setProjectType(getDicCheckboxWorth(project.getProjectType(), Constant.DICTIONTRY_PROJECTTYPE));
        project.setResearchField(getDicCheckboxWorth(project.getResearchField(), Constant.DICTIONTRY_PROJECTFIELD));
        project.setAreaWorth(getAreaWorth(project.getArea(), project.getDomesticOrForeign()));
        project.setTechnicalWorth(getDicSingleWorth(project.getTechnical(), Constant.DICTIONTRY_PROJECTTECHNICAL));
        model.addAttribute("project", project);
        model.addAttribute("projectAttr", projectAttr);
        model.addAttribute("collectPersonName", userService.getById(project.getCollectPersonId()).getFullName());
        
        //查询联系人信息
        Person person = new Person(); 
        if (StringUtil.isNotEmpty(project.getProjectContactId())) {
	        person = personService.findPersonByPid(project.getProjectContactId());
	    	person.setSourceWorth(getDicSingleWorth(person.getSource(), Constant.DICTIONTRY_PROJECTSOURCE));
			person.setTypeWorth(getDicSingleWorth(person.getType(), Constant.DICTIONTRY_PERSONTYPE));
			person.setResearchField(getDicCheckboxWorth(person.getResearchField(), Constant.DICTIONTRY_PROJECTFIELD));
			if (StringUtil.isNotEmpty(person.getTalentLevel())) {
				person.setTalentLevel(getDicCheckboxWorth(person.getTalentLevel(), Constant.DICTIONTRY_TALENTLEVEL));
			}
			person.setAreaWorth(getAreaWorth(person.getArea(), person.getDomesticOrForeign()));
        }
        model.addAttribute("person",person);
        //查询持有人
        List<Person> holderList = holderList(projectId);
        model.addAttribute("holderList",holderList);
        
        if (StringUtil.isNotEmpty(demandId)) {
        	ButtDetails queryButt = new ButtDetails();
        	queryButt.setButtPersonId(getUserId(request));
        	queryButt.setFuture(1);
        	queryButt.setDemandNumber(demandId);
        	queryButt.setProjectNumber(projectId);
        	List<ButtDetails> buttDetailList = detailsService.findButtDetails(queryButt);
        	model.addAttribute("buttDetailList", buttDetailList);
        	model.addAttribute("demand", demandService.getById(demandId));
        }
        //查询关联的客户
        List<Customer> customerList = projectService.queryCustomer(projectId);
        customerList.forEach(cus -> cus.setCurrentStateName(getDicSingleWorth(cus.getCurrentState(), Constant.DICTIONTRY_CURRENTSATUS)));
        model.addAttribute("customerList", customerList);
        
      //lookExpert为1表示要查看联系方式
        if (lookExpert != null && lookExpert.equals(1)) 
        	checkLookExpert(expertId, lookPwd, request);
        return "project/showDetail";
    }
    
    /**
     * 添加项目索引
     * @param project
     * @param projectAttr
     * @param isolr
     * @return
     */
	private boolean addProjectIsolr(Project project, ProjectAttr projectAttr, IsolrOperation<LuceneProject> isolr) {
    	LuceneProject luceneProject = luceneProjectConversion(project, projectAttr);
    	List<LuceneProject> list = new ArrayList<>();
    	list.add(luceneProject);
    	return isolr.add("project", list);
    }
    
	/**
	 * 修改项目索引
	 * @param project
	 * @param projectAttr 不变就传null
	 * @param isolr
	 * @return
	 */
    private boolean updateProjectIsolr(Project project, ProjectAttr projectAttr, IsolrOperation<LuceneProject> isolr, boolean fromDB) {
    	if (fromDB) {
    		project.setProjectTypeInteger(Integer.parseInt(project.getProjectType()));
    		project.setResearchFieldInteger(Integer.parseInt(project.getResearchField()));
    	}
    	LuceneProject luceneProject = luceneProjectConversion(project, projectAttr);
    	return isolr.update("project", luceneProject);
    }
    
    private LuceneProject luceneProjectConversion(Project project, ProjectAttr projectAttr) {
    	LuceneProject luceneProject = new LuceneProject();
    	luceneProject.setProjectId(project.getPid());
    	if (project.getProjectNumber() != null)
    		luceneProject.setProjectNumber("R"+project.getProjectNumber());
    	luceneProject.setSource(getDicSingleWorth(project.getSourceId(), Constant.DICTIONTRY_PROJECTSOURCE));
    	luceneProject.setSourceRemark(project.getSourceRemark());
    	String projectTypeWorth = getDicCheckboxWorth(project.getProjectTypeInteger().toString(), Constant.DICTIONTRY_PROJECTTYPE);
		luceneProject.setProjectType(Stream.of(projectTypeWorth.split(",")).collect(Collectors.toList()));
		String researchFieldWorth = getDicCheckboxWorth(project.getResearchFieldInteger().toString(), Constant.DICTIONTRY_PROJECTFIELD);
		luceneProject.setResearchField(Stream.of(researchFieldWorth.split(",")).collect(Collectors.toList()));
		luceneProject.setArea(getAreaWorth(project.getArea(), project.getDomesticOrForeign()));
		luceneProject.setProjectName(project.getProjectName());
		luceneProject.setProjectStatus(getDicSingleWorth(project.getProjectStatus(), Constant.DICTIONTRY_PROJECTSTATUS));
		luceneProject.setIntroduction(project.getIntroduction());
		luceneProject.setKeyWords(project.getKeyWords());
		luceneProject.setProjectHolder(holderList(project.getPid()).stream().map(Person::getName).collect(Collectors.toList()));
		luceneProject.setProjectContactId(project.getProjectContactId());
		String projectContactName = StringUtil.isEmpty(project.getProjectContactId()) ? null : personService.getById(project.getProjectContactId()).getName();
		luceneProject.setProjectContactName(projectContactName);
		luceneProject.setTechnical(getDicSingleWorth(project.getTechnical(), Constant.DICTIONTRY_PROJECTTECHNICAL));
		if (projectAttr != null) {
			luceneProject.setProjectRequirements(projectAttr.getProjectRequirements());
			luceneProject.setMarketProspect(projectAttr.getMarketProspect());
			luceneProject.setTechnicalMaturity(projectAttr.getTechnicalMaturity());
		}
    	return luceneProject;
    }
    
    private boolean addPersonIsolr(Person person, IsolrOperation<LucenePerson> isolr) {
    	LucenePerson lucenePerson = lucenePersonConversion(person);
    	List<LucenePerson> list = new ArrayList<>();
    	list.add(lucenePerson);
    	return isolr.add("person", list);
    }
    
    private boolean updatePersonIsolr(Person person, IsolrOperation<LucenePerson> isolr, boolean fromDB) {
    	//person如果是从数据库中查出来的
    	if (fromDB) {
    		person.setResearchFieldInteger(Integer.parseInt(person.getResearchField()));
    		if (StringUtil.isNotEmpty(person.getTalentLevel()))
    			person.setTalentLevelInteger(Integer.parseInt(person.getTalentLevel()));
    	}
    	LucenePerson lucenePerson = lucenePersonConversion(person);
    	return isolr.update("person", lucenePerson);
    }
    
    private LucenePerson lucenePersonConversion(Person person) {
    	LucenePerson lp = new LucenePerson();
    	lp.setExpertId(person.getPid());
    	if (person.getExpertNumber() != null)
    		lp.setExpertNumber("E"+person.getExpertNumber());
    	lp.setSource(getDicSingleWorth(person.getSource(), Constant.DICTIONTRY_PROJECTSOURCE));
    	lp.setType(getDicSingleWorth(person.getType(), Constant.DICTIONTRY_PERSONTYPE));
    	String researchFieldWorth = getDicCheckboxWorth(person.getResearchFieldInteger().toString(), Constant.DICTIONTRY_PROJECTFIELD);
    	lp.setResearchField(Stream.of(researchFieldWorth.split(",")).collect(Collectors.toList()));
    	lp.setArea(getAreaWorth(person.getArea(), person.getDomesticOrForeign()));
    	if(StringUtil.isNotEmpty(person.getTalentLevel())){
    		String talentLevelWorth = getDicCheckboxWorth(person.getTalentLevelInteger().toString(), Constant.DICTIONTRY_TALENTLEVEL);
    		lp.setTalentLevel(Stream.of(talentLevelWorth.split(",")).collect(Collectors.toList()));
    	}
    	lp.setName(person.getName());
    	lp.setSchoolAndMajor(person.getSchoolAndMajor());
    	lp.setUnit(person.getUnit());
    	lp.setTitle(person.getTitle());
    	lp.setProfessionaField(person.getProfessionaField());
    	lp.setEducation(person.getEducation());
    	lp.setWorkExp(person.getWorkExp());
    	lp.setHonorAward(person.getHonorAward());
    	lp.setTechnica(person.getTechnica());
    	return lp;
	}
    
    @RequestMapping("/showHolderAddProject")
    public String showHolderAddProject(Model model, String personId, Project project, String searchKeyword, @RequestParam(defaultValue = "1") int pageNo, HttpServletRequest request) {
    	searchPageInfo(model, project, searchKeyword, pageNo, request);
    	ProjectOfPerson pop = new ProjectOfPerson();
    	pop.setPersonId(personId);
		List<ProjectOfPerson> popList = projectOfPersonService.queryAll(pop);
    	List<String> linkedProjectIdList = popList.stream().map(ProjectOfPerson::getProjectId).collect(Collectors.toList());
    	model.addAttribute("linkedProjectIdList", linkedProjectIdList);
    	return "project/showHolderAddProject";
    }
    
    @ResponseBody
    @RequestMapping("/linkHolder")
    public String linkHolder(String personId, String projectId) {
    	personService.linkHolder(projectId, personId);
    	return "success";
    }
    
    /**
     * 添加联系人有弹出框，然后选择了修改就执行该方法
     * @author pdz
     * @date 2018年10月29日
     * @param projectId
     * @param projectContactId
     * @return
     */
    @RequestMapping("/showLinkUpdateContact")
    public String showLinkUpdateContact(Model model, HttpServletRequest request, String projectId, String projectContactId) {
    	return showUpdateContact(model, projectContactId, request);
    }
    
    /**
     * 先修改联系人然后直接关联
     * @author pdz
     * @date 2018年10月29日
     * @param person
     * @param projectId
     * @return
     */
    @RequestMapping("/linkUpdateContact")
    public String linkUpdateContact(Person person, BindingResult bindingResult, Model model, MultipartFile file, HttpServletRequest request, String projectId) {
    	updateContact(person, bindingResult, model, file, request, projectId);
    	return linkContact(person.getPid(), projectId);
    }
    
    @RequestMapping("/linkContact")
    public String linkContact(String personId, String projectId) {
    	Project project = projectService.getById(projectId);
    	project.setProjectContactId(personId);
    	projectService.updateProjectContact(project);
    	updateProjectIsolr(project, null, new SolrOperation<>(), true);
    	return "redirect:/project/showDetail?projectId="+projectId;
    }
    
    @RequestMapping("/linkHolder1")
    public String linkHolder1(Model model, String personId, String projectId) {
    	personService.linkHolder(projectId, personId);
    	return "redirect:/project/showHolders?projectId="+projectId;
    }
    
    @RequestMapping("/showLinkUpdateHolder1")
    public String showLinkUpdateHolder1(Model model, String personId, String projectId) {
    	model.addAttribute("next", "linkUpdateHolder1");
    	return showUpdateHolder(model, personId, projectId);
    }
    
    @RequestMapping("/linkUpdateHolder1")
    public String linkUpdateHolder1(Person person, BindingResult bindingResult, Model model, String projectId,
    		MultipartFile file, HttpServletRequest request) {
    	updateHolder(person, bindingResult, model, projectId, file, request);
    	return linkHolder1(model, person.getPid(), projectId);
    }
    
    /**
     * 添加项目时通过名称查询项目，如有相同名称的则弹窗显示
     * @author pdz
     * @date 2018年11月2日
     * @param projectName
     * @return
     */
    @RequestMapping("/checkName")
    @ResponseBody
    public List<Project> checkName(String projectName) {
    	Project pro = new Project();
    	pro.setProjectName(projectName);
    	List<Project> projectList = projectService.queryAll(pro);
    	projectList.forEach(project -> {
    		project.setProjectType(getDicCheckboxWorth(project.getProjectType(), Constant.DICTIONTRY_PROJECTTYPE)); 
    		project.setProjectStatusWorth(getDicSingleWorth(project.getProjectStatus(), Constant.DICTIONTRY_PROJECTSTATUS));
    	});
		return projectList;
    }
    
    @RequestMapping("/detailStatistics")
	public String detailStatistics(String beginDate, String endDate, String userId, @RequestParam(defaultValue="1") Integer pageNo, Model model) {
		PageHelper.startPage(pageNo, DEFAULT_COUNT);
		List<Project> list = projectService.detailStatistics(beginDate, endDate, userId);
		PageInfo<Project> pageInfo = new PageInfo<>(list);
		List<User> userList = userService.queryInPidList(pageInfo.getList().stream().map(Project::getCollectPersonId).distinct().collect(Collectors.toList()));
		pageInfo.getList().forEach(pro -> {
			pro.setCollectPersonId(userList.stream().filter(user -> pro.getCollectPersonId().equals(user.getPid())).map(User::getFullName).findAny().get());
			pro.setProjectType(getDicCheckboxWorth(pro.getProjectType(), Constant.DICTIONTRY_PROJECTTYPE)); 
			pro.setProjectStatusWorth(getDicSingleWorth(pro.getProjectStatus(), Constant.DICTIONTRY_PROJECTSTATUS));
		});
		model.addAttribute("pageInfo", pageInfo);
		model.addAttribute("pageInfo_project", true);
		model.addAttribute("route", "/project");
		return "detailStatistics";
	}
    
    @RequestMapping("/showSelf")
    public String showSelf(HttpServletRequest request) {
    	return "redirect:/project/showConditionQuery?collectPersonId="+getUserId(request);
    }
    
    @RequestMapping("/downWord")
    public void downWord(String projectId, HttpServletRequest request, HttpServletResponse response) {
    	Project project = projectService.getById(projectId);
    	Map<String,String> dataMap = new HashMap<>();
    	dataMap.put("proNum", "R"+project.getProjectNumber());
    	dataMap.put("projectName", project.getProjectName());
    	dataMap.put("projectHolder", StrUtil.ifNullToEmpty(holderList(projectId).stream().map(Person::getName).collect(Collectors.joining(", "))));
    	String projectContactId = project.getProjectContactId();
    	dataMap.put("projectContact", "");
    	dataMap.put("email", "");
    	dataMap.put("tell", "");
		if (StringUtil.isNotEmpty(projectContactId)) {
    		Person person = personService.getById(projectContactId);
    		dataMap.put("projectContact", person.getName());
    		String email = person.getEmail();
    		email = StringUtil.isNotEmpty(email) && email.length() > 4 ? "****" + email.substring(4) : email;
			dataMap.put("email", StrUtil.ifNullToEmpty(email));
    		String tell = person.getTell();
    		tell = StringUtil.isNotEmpty(tell) && tell.length() > 4 ? tell.substring(0, tell.length()/2-2) + "****" + tell.substring(tell.length()/2+2) : tell; 
			dataMap.put("tell", StrUtil.ifNullToEmpty(tell));
    	}
		dataMap.put("introduction", StrUtil.ifNullToEmpty(project.getIntroduction()));
		dataMap.put("words", StrUtil.ifNullToEmpty(project.getKeyWords()));
		dataMap.put("researchField", getDicCheckboxWorth(project.getResearchField(), Constant.DICTIONTRY_PROJECTFIELD));
		dataMap.put("technicalWorth", getDicSingleWorth(project.getTechnical(), Constant.DICTIONTRY_PROJECTTECHNICAL));
		ProjectAttr projectAttr = projectAttrService.findByProjectId(projectId);
		dataMap.put("marketProspect", StrUtil.ifNullToEmpty(projectAttr.getMarketProspect()));
		dataMap.put("projectRequirements", StrUtil.ifNullToEmpty(projectAttr.getProjectRequirements()));
		dataMap.put("buttDetail", "");
		ExcelUtil.downWord(dataMap, StrUtil.getCurrentDateTime("yyyyMMddHHmmss") + "-R" + project.getProjectNumber()+".doc", "project_template.ftl", request, response);
    }
    
    @RequestMapping("/updateDetailStatistics")
    public String updateDetailStatistics(String beginDate, String endDate, String userId, Integer operaIndex, String fullname, @RequestParam(defaultValue="1") Integer pageNo, Model model) {
    	List<String> projectIdList = queryUpdateLog(beginDate, endDate, userId, operaIndex);
    	PageHelper.startPage(pageNo, DEFAULT_COUNT);
    	List<Project> list = projectService.queryInPidList(projectIdList);
    	PageInfo<Project> pageInfo = new PageInfo<>(list);
    	pageInfo.getList().forEach(pro -> {
			pro.setCollectPersonId(fullname);
			pro.setProjectType(getDicCheckboxWorth(pro.getProjectType(), Constant.DICTIONTRY_PROJECTTYPE)); 
			pro.setProjectStatusWorth(getDicSingleWorth(pro.getProjectStatus(), Constant.DICTIONTRY_PROJECTSTATUS));
		});
		model.addAttribute("pageInfo", pageInfo);
		model.addAttribute("pageInfo_project", true);
		model.addAttribute("route", "/project");
		return "detailStatistics";
    }
    
    /**
     * 下载项目附件
     * @author pdz
     * @date 2019年1月24日
     */
    @RequestMapping("/downAnnex")
    public void downAnnex(String fileName, HttpServletResponse response) {
    	File file = new File(Constant.DEF_PROJECT_PATH, fileName);
    	try {
			FileUtils.downLoad(file, response);
		} catch (Exception e) {
			e.printStackTrace();
		}
    }
}
